import time
import asyncio

from funasr.utils.postprocess_utils import rich_transcription_postprocess
from tqdm import tqdm

from interview_voice_project.__001__langgraph_more_node import AgentState
from interview_voice_project.__003__fastapi import update_mysql
from interview_voice_project.common import my_voice_model, config_ini
from interview_voice_project.__002__db_helper_parse.db_helper import my_db_helper


def _sync_generate_text(voice_path):
    res = my_voice_model.generate(
        input=voice_path,
        cache={},
        language="auto",
        use_itn=True,
        batch_size_s=60,
        merge_vad=True,
        merge_length_s=15,
    )
    texts = []
    for item in res:
        texts.append(rich_transcription_postprocess(item["text"]))
    return "".join(texts)


async def voice_to_text_node(state: AgentState):
    await update_mysql("开始语音转文本", record_id=state["record_id"])
    split_audio_path_list = state['split_audio_path_list']
    # 获取voice路径
    start_ts = time.time()
    max_concurrency = int((config_ini.VOICE_MODEL.MAX_CONCURRENCY or "2").strip())
    sem = asyncio.Semaphore(max_concurrency)

    async def worker(idx, path):
        t0 = time.time()
        async with sem:
            try:
                text = await asyncio.to_thread(_sync_generate_text, path)
            except Exception as e:
                print({"segment": idx + 1, "error": str(e)})
                text = ""
            # 估算剩余时间
            elapsed = time.time() - start_ts
            done = idx + 1
            total = len(split_audio_path_list)
            eta_sec = int((elapsed / max(1, done)) * max(0, total - done))
            mm, ss = divmod(eta_sec, 60)
            await update_mysql(f"正在处理第{done}/{total}块，预计剩余 {mm}分{ss}秒。", record_id=state["record_id"])
            # 增量保存到DB
            try:
                recs = my_db_helper.get_all_interview_records({"id": state["record_id"]})
                prev = (recs[0].get("interview_text", "") if recs and isinstance(recs[0], dict) else "")
                my_db_helper.update_interview_record(state["record_id"], {"interview_text": prev + text})
            except Exception:
                pass
            return idx, text, time.time() - t0

    tasks = [worker(i, p) for i, p in enumerate(split_audio_path_list)]
    results = await asyncio.gather(*tasks)
    results.sort(key=lambda x: x[0])
    voice_text_list = [r[1] for r in results]
    total_time = time.time() - start_ts
    avg_time = total_time / max(1, len(split_audio_path_list))
    print({"total_time_s": round(total_time, 3), "avg_segment_time_s": round(avg_time, 3), "segments": len(split_audio_path_list)})
    state['voice_text_list'] = voice_text_list
    await update_mysql("完成语音转文本", record_id=state["record_id"])
    return state


if __name__ == '__main__':
    voice_to_text_node({"split_audio_path_list": [
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_001.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_002.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_003.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_004.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_005.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_006.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_007.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_008.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_009.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_010.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_011.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_012.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_013.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_014.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_015.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_016.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_017.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_018.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_019.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_020.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_021.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_022.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_023.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_024.wav',
        '/Users/duyi/PycharmProjects/interview_voice_project/voice/20250927_201420_罗培鑫面试/20250927_201420_罗培鑫面试_segment_025.wav']})
